﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


static class Fitness
{
    public static DailyProgram
    GenerateProgram(UserInfo user, int seed, FreeTime free_time) {

        seed *= 366;
        seed += DateTime.Today.DayOfYear;
        var rand = new Random(seed);

        var food_infos = Helpers.Shuffle(Helpers.GetFoodInfos(), seed);
        if (user.IsVegetarian) {
            food_infos = food_infos.Where(_f => !_f.HasMeat);
        }

        var exercise_infos = Helpers.Shuffle(Helpers.GetExerciseInfos(), seed);
        // todo - shuffle based on rand?

        var food_stack = new Stack<FoodInfo>(food_infos);
        var exercise_stack = new Stack<ExerciseInfo>(exercise_infos);

        var eating = new List<MealItem>();
        var exercises = new List<ExerciseSet>();

        // var calories = GetCaloricTargetPerDay(user);
        // var proteins = GetProteinTargetPerDay(user);

        // 8:00
        var time = free_time.GetStartTime();

        // morning routine
        eating.Add(new MealItem(1, food_stack.Pop(), time));

        // 8:15
        // todo


        exercises.Add(new ExerciseSet(rand.Next(10, 20), exercise_stack.Pop(), time + 0.25));
        exercises.Add(new ExerciseSet(rand.Next(10, 20), exercise_stack.Pop(), time + 0.25));

        // todo - what if free time runs out?

        // 9:00
        free_time.RemoveRange(time, time + 1.0);
        time = free_time.GetStartTime();

        // breakfast
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));

        // 13:00
        free_time.RemoveRange(time, time + 4.0);
        time = free_time.GetStartTime();

        // lunch 

        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));


        // afternoon exercise

        // 16:00
        free_time.RemoveRange(time, time + 3.0);
        time = free_time.GetStartTime();

        exercises.Add(new ExerciseSet(rand.Next(10, 20), exercise_stack.Pop(), time));
        exercises.Add(new ExerciseSet(rand.Next(10, 20), exercise_stack.Pop(), time));
        exercises.Add(new ExerciseSet(rand.Next(10, 20), exercise_stack.Pop(), time));

        // afternoon snack

        // 17:00
        free_time.RemoveRange(time, time + 1.0);
        time = free_time.GetStartTime();

        eating.Add(new MealItem(1, food_stack.Pop(), time));

        // dinner

        // 20:30

        free_time.RemoveRange(time, time + 3.5);
        time = free_time.GetStartTime();

        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));
        eating.Add(new MealItem(rand.Next(1, 3), food_stack.Pop(), time));

        var ret = new DailyProgram(eating, exercises);
        return ret;
    }

    static double GetCaloricTargetPerDay(UserInfo user) {
        throw new NotImplementedException();
    }
    static double GetProteinTargetPerDay(UserInfo user) {
        throw new NotImplementedException();
    }

}

